from log_manager import LogManager
from serial_protocol import SerialProtocol
from file_transfer_manager import FileTransferManager
from protocol_parser import ProtocolParser
from error_handler import ErrorHandler
import os

class DeviceManager:
    def __init__(self, config):
        self.protocol = None
        self.device_info = None
        self.disk_info = None
        self.config = config
    def connect(self, port):
        """连接设备
        
        Args:
            port: 串口名称
            baudrate: 波特率
            
        Returns:
            bool: 是否连接成功
        """
        try:
            # 启动接收线程
            self.protocol = SerialProtocol(port, self.config['baudrate'])
            self.transfer_manager = FileTransferManager(self.protocol, self)
            LogManager.info(f"连接设备: {port}, 波特率: {self.config['baudrate']}") 
            
            # 获取设备信息
            self.device_info = self.get_device_info()
            if not self.device_info:
                raise Exception("获取设备信息失败")
                
            # 获取磁盘信息  
            self.disk_info = self.get_disk_info()
            if not self.disk_info:
                raise Exception("获取磁盘信息失败")
                
            return True
        except Exception as e:
            LogManager.error(f"连接设备失败: {str(e)}")
            self.disconnect()
            return False
            
    def disconnect(self):
        """断开连接"""
        if self.protocol:
            self.protocol.close()
            self.protocol = None
            self.transfer_manager = None
            
    def get_device_info(self):
        """获取设备信息"""
        if not self.protocol:
            return None
            
        try:
            # 发送获取设备信息命令
            self.protocol.send_command(ProtocolParser.CMD_GET_DEVICE_INFO)
            
            # 等待响应
            response = self.protocol.wait_response_data(ProtocolParser.CMD_GET_DEVICE_INFO)
            if not response:
                raise Exception("获取设备信息失败")
                
            # 解析设备信息
            info = self.protocol.parser.parse_device_info(response)
            if not info:
                raise Exception("解析设备信息失败")
                
            # 保存设备信息
            self.device_info = info
            LogManager.info(f"设备信息: {info}")
            return info
            
        except Exception as e:
            LogManager.error(f"获取设备信息失败: {str(e)}")
            return None
        
    def list_device_files(self, path):
        """获取文件列表
        
        Args:
            path: 要列出的目录路径
            
        Returns:
            list: 文件列表，失败返回None
        """
        try:
            if not self.protocol:
                raise Exception("设备未连接")
                
            # 发送获取文件列表命令
            LogManager.debug(f"获取文件列表: {path}")
            self.protocol.send_command(
                ProtocolParser.CMD_GET_FILE_LIST,
                path.encode('utf-8') + b'\0'  # 添加结束符
            )
            
            # 等待响应
            response = self.protocol.wait_response_data(ProtocolParser.CMD_GET_FILE_LIST)
            if not response:
                raise Exception("获取文件列表失败")
                
            # 解析文件列表
            files = self.protocol.parser.parse_file_list(response)
            if files is None:
                raise Exception("解析文件列表失败")
                
            LogManager.debug(f"文件列表: {files}")
            return files
            
        except Exception as e:
            LogManager.error(f"获取文件列表失败: {str(e)}")
            return None
        
    def get_disk_info(self):
        """获取U盘信息"""
        if not self.protocol:
            return None
            
        self.protocol.send_command(self.protocol.parser.CMD_GET_UDISK_INFO)
        response = self.protocol.wait_response_data(
            self.protocol.parser.CMD_GET_UDISK_INFO)
            
        if response:
            self.disk_info = self.protocol.parser.parse_udisk_info(response)
            return self.disk_info
        return None
        
    def create_directory(self, path):
        """创建目录"""
        if not self.protocol:
            return False
            
        self.protocol.send_command(
            self.protocol.parser.CMD_MKDIR,
            path.encode('utf-8')
        )
        return self.protocol.wait_response(self.protocol.parser.CMD_MKDIR)
        
    def transfer_file(self, remote_path, local_path, is_upload=True, file_size=None, is_folder_transfer=False):
        """传输文件
        
        Args:
            remote_path: 远程文件路径
            local_path: 本地文件路径
            is_upload: 是否为上传
            file_size: 文件大小（下载时需要）
            is_folder_transfer: 是否是文件夹传输的一部分
            
        Returns:
            bool: 是否成功
        """
        try:
            if is_upload:
                # 检查本地文件是否存在
                if not os.path.exists(local_path):
                    raise FileNotFoundError(f"本地文件不存在: {local_path}")
                    
                # 获取文件大小
                file_size = os.path.getsize(local_path)
                
                # 开始传输
                return self.transfer_manager.transfer_file_to_device(
                    local_path, 
                    remote_path,
                    is_folder_transfer=is_folder_transfer  # 传递文件夹传输标志
                )
            else:
                # 检查文件大小是否有效
                if file_size is None or file_size < 0:
                    raise ValueError("无效的文件大小")
                    
                # 开始传输
                return self.transfer_manager.transfer_file_from_device(
                    remote_path,
                    local_path,
                    file_size,
                    is_folder_transfer=is_folder_transfer  # 传递文件夹传输标志
                )
                
        except Exception as e:
            LogManager.error(f"传输失败 185: {str(e)}")
            return False
            
    def cancel_transfer(self):
        """取消传输"""
        if self.transfer_manager:
            self.transfer_manager.cancel_transfer()
            
    def format_size(self, size):
        """格式化文件大小"""
        if size < 1024:
            return f"{size} B"
        elif size < 1024 * 1024:
            return f"{size/1024:.1f} KB"
        else:
            return f"{size/(1024*1024):.1f} MB" 
        
    def is_connected(self):
        """检查设备是否已连接
        
        Returns:
            bool: 如果设备已连接返回True，否则返回False
        """
        return self.protocol is not None and self.protocol.is_open() 
        
    def get_available_ports(self):
        """获取可用的串口列表
        
        Returns:
            list: 可用串口列表
        """
        try:
            import serial.tools.list_ports
            ports = []
            for port in serial.tools.list_ports.comports():
                ports.append(port.device)
            return ports
        except Exception as e:
            LogManager.error(f"获取串口列表失败: {str(e)}")
            return [] 